#pragma once

#include "VulkanRHI.h"
#include "Texture/RHITexture.h"
#include "Texture/RHISampler.h"
#include <functional>
#include "Tradition/RHISemaphore.h"

class SwapChain
{
	friend class ImguiGUI;
public:

	void Init();

	void Exit();

	void AddWaitSemaphore(RefCountPtr<RHISemaphore> semaphore);

	void AddSignalSemaphore(RefCountPtr<RHISemaphore> semaphore);

	void UpdateTexture(RefCountPtr<RHITexture> texture);

	void SubmitFrame();

public:

	uint32 GetImageCount() const;

	VkExtent2D GetSwapchainExtent() const;

	VkFormat GetSwapChainFormat() const;

	void OnResize();

	VkCommandBuffer BeginRecordCommand();

	void EndRecordCommand(std::function<void()> onUpdateCommand);

protected:

	void CreateSwapchain();

	void CreateRenderPass();

	void CreateDescriptor();

	void CreatePipeline();

	void CreateFramebuffers();

	void CreateCommandBuffers();

	void CreateSyncObjects();

	void CleanupSwapchain();

	VkImageView CreateImageView(VkImage image, VkFormat format, VkImageAspectFlags aspectFlags);

protected:

	VkSwapchainKHR mSwapchain;

	VkFormat mFormat;

	uint32 mImageCount;

	VkExtent2D mSwapchainExtent;

	std::vector<VkImage> mImages;

	std::vector<VkImageView> mImageViews;

	VkRenderPass mRenderPass;

	VkDescriptorSetLayout mDescriptorSetLayout;

	VkPipelineLayout mPipelineLayout;

	VkDescriptorPool mDescriptorPool;

	std::vector<VkDescriptorSet> mDescriptorSets;

	VkPipeline mPipeline;

	std::vector<VkFramebuffer> mFramebuffers;

	std::vector<VkCommandBuffer> mCommandBuffers;

	RefCountPtr<RHISampler> mResultSampler;

	std::vector<VkSemaphore> mImageAvailableSemaphores;

	std::vector<VkSemaphore> mRenderFinishedSemaphores;

	std::vector<VkFence> mCommandCompletedFences;

	std::vector<RefCountPtr<RHISemaphore>> mWaitSemaphores;

	std::vector<RefCountPtr<RHISemaphore>> mSignalSemaphores;
};